package com.dream.service.recommender.impl;

import com.alibaba.fastjson.JSONObject;
import com.dream.common.model.response.BaseResponse;
import com.dream.common.model.response.ErrorCode;
import com.dream.service.recommender.RecomenderServiceFactory;
import com.dream.service.recommender.cache.RouteCacheImpl;
import com.dream.service.recommender.splitter.computer.Computer;
import com.dream.service.recommender.toolkits.utils.RecConfigUtil;
import com.dream.service.recommender.toolkits.utils.StringUtils;
import com.dream.service.recommender.util.MercuryUrlManager;
import com.dream.service.recommender.api.RecommenderService;
import com.dream.service.recommender.api.RouteService;
import com.dream.service.recommender.domain.model.UserInfo;
import com.dream.service.recommender.domain.request.BaseRequest;
import com.dream.service.recommender.domain.request.FrontParam;
import com.dream.service.recommender.domain.request.RegisterService;
import com.dream.service.recommender.domain.response.RecommenderData;
import com.dream.service.recommender.domain.splitter.ExpConfig;
import com.dream.service.recommender.domain.splitter.SplitterRequest;
import org.apache.log4j.Logger;

import java.util.HashMap;
import java.util.Map;

/**
 *  Created by zhiji on 2016/3/15.
 */
public class RouteServiceImpl implements RouteService {

    private Logger logger = Logger.getLogger(RouteServiceImpl.class);


    /**
     * 暂时只是放内存，后期会进行其他处理
     * rec_id和dubbo bean那么的映射，后期提供注册功能后会发生变化
     */
    private Map<String, String> registerServiceMap = new HashMap<String, String>();

    //分流策略
    private Computer computer;

    private RouteCacheImpl routeCache = new RouteCacheImpl();

    public Computer getComputer() {
        return computer;
    }

    public void setComputer(Computer computer) {
        this.computer = computer;
    }

    @Override
    public BaseResponse<RecommenderData> getRecommender(BaseRequest<FrontParam> request) {
        BaseResponse<RecommenderData> rec_response = new BaseResponse<RecommenderData>();
        try {
            if (request == null || request.getParam() == null) {
                logger.error("Param Error." + JSONObject.toJSONString(request));
                return buildResponseResult(rec_response, false, ErrorCode.PARAM_ERROR.getCode(), "Param Error.");
            }
            FrontParam frontParam = request.getParam();
            String rec_id = frontParam.getRec_id();
            //分流策略处理,先默认返回第一个,没有异常处理
            if (computer != null){
                SplitterRequest splitterRequest = new SplitterRequest();
                UserInfo user = frontParam.getUser();
                if(user != null ) {
                    splitterRequest.setPin(user.getPin());
                    splitterRequest.setUuid(user.getUuid());
                    ExpConfig expConfig = computer.getExp(Long.parseLong(rec_id), splitterRequest);
                    if ( expConfig != null){
                        long exp_id = expConfig.getExp_id();
                        rec_id = rec_id.concat("_" + exp_id);
                    }
                }
            }
            String consumer_type = registerServiceMap.get(rec_id);
            if (StringUtils.isEmpty(consumer_type)) {
                return buildResponseResult(rec_response, false, ErrorCode.PARAM_ERROR.getCode(), "Invaild RecID.");
            }

            RecommenderService recommenderService = RecomenderServiceFactory.getRecommenderService(consumer_type);
            if (recommenderService == null) {
                return buildResponseResult(rec_response, false, ErrorCode.PARAM_ERROR.getCode(), "Invaild Rec Config.");
            }
            if (RouteCacheImpl.routeCacheStrategyMap.containsKey(rec_id)) { // 走缓存
                System.out.println("走缓存");
                RecommenderData recommenderData = routeCache.readResultFromCache(request.getParam());
                if (recommenderData != null) { // 缓存中有结果
                    logger.debug("cache result==="+JSONObject.toJSONString(recommenderData));
                    rec_response.setResult(recommenderData);
                    buildResponseResult(rec_response, true, ErrorCode.OK.getCode(), "From Cache");
                } else { // 缓存中无结果，击穿
                    rec_response = recommenderService.getRecommender(request);
                    if (rec_response.isSuccess() && rec_response.getResult() != null) {
                        routeCache.writeResultIntoCache(rec_response.getResult(), request.getParam());
                    }
                }
            } else {
                rec_response = recommenderService.getRecommender(request);
            }
            if (rec_response.isSuccess() && rec_response.getResult() != null) {
                MercuryUrlManager.setMercuryUrl(rec_response.getResult(), frontParam);
            }
            return rec_response;
        } catch (Exception e) {
            logger.error("RouteServiceImpl===>getRecommender:::",e);
            return buildResponseResult(rec_response, false, ErrorCode.PROCESS_ERROR.getCode(), "Route Process Error.");
        }
    }

    private BaseResponse buildResponseResult(BaseResponse  baseResponse,boolean success, int error_code, String error_msg){
        if(baseResponse==null){
            baseResponse = new BaseResponse();
        }
        baseResponse.setSuccess(success);
        baseResponse.setError_code(error_code);
        baseResponse.setError_msg(error_msg);
        return baseResponse;
    }

    @Override
    public BaseResponse<Boolean> registerService(BaseRequest<RegisterService> recommdenderService) {
        //注册过程
        return null;
    }

    //load已经存在的client
    @Override
    public void init() {
        registerServiceMap = RecConfigUtil.getRecInfo();
    }

}
